//
// Created by martin on 2/8/22.
//

#ifndef MUDUO_POLLER_H
#define MUDUO_POLLER_H

#include "muduo/base/Timestamp.h"
#include "muduo/net/EventLoop.h"

#include <map>
#include <vector>

namespace muduo
{
namespace net
{

class Channel;

/**
 * IO Multiplexing Interface
 * Support poll(2), epoll(7)
 *
 * Only owner EventLoop IO thread can invoke it, so thread safe is not necessary.
 */
/**
* IO复用接口
* 禁止编译器生成copy构造函数和copy assignment
* 支持poll(2), epoll(7)
*/
class Poller : noncopyable
{
public:
    typedef std::vector<Channel*> ChannelList;
    explicit Poller(EventLoop* loop);
    virtual ~Poller();
    /**
     * Polls the I/O events.
     * Must be called in the loop thread.
     * poll(2) for PollPoller, epoll_wait(2) for EPollPoller
     */
    /*
     * 监听函数，根据激活的通道列表，监听指定fd的相应事件
     * 对于PollPoller会调用epoll_wait(2), 对于EPollPoller会调用poll(2)
     *
     * 返回调用完epoll_wait/poll的当前时间（Timestamp对象）
     */
    virtual Timestamp poll(int timeoutMs, ChannelList* activeChannels) = 0;
    /**
     * Update channel listened
     */
    /* 更新监听通道的事件 */
    virtual void updateChannel(Channel* channel) = 0;
    /* 删除监听通道 */
    virtual void removeChannel(Channel* channel) = 0;
    /* 判断当前Poller对象是否持有指定通道 */
    virtual bool hasChannel(Channel* channel) const;
    /* 默认创建Poller对象的类函数 */
    static Poller* newDefaultPoller(EventLoop* loop);
    /*
     * 断言所属EventLoop为当前线程.
     * 如果断言失败，将终止程序（LOG_FATAL）
     */
    void assertInLoopThread() const
    {
        ownerLoop_->assertInLoopThread();
    }
protected:
    /*
     * 该类型保存fd和需要监听的events，以及各种事件回调函数（可读/可写/错误/关闭等）
     */
    typedef std::map<int, Channel*> ChannelMap;
    // Poller don't own the Channel, so the channel must be unregister(EventLoop::removeChannel) before its dtor.
    // std::map used for speeding up to find out a channel by fd
    /* 保存所有事件的Channel，一个Channel绑定一个fd */
    ChannelMap channels_;
private:
    /*
     * 事件驱动循环, 用于调用poll监听fd事件
     */
    EventLoop* ownerLoop_;
};

} // namespace net
} // namespace muduo

#endif //MUDUO_POLLER_H
